package cn.fintecher.pangolin.service.business.service;


import cn.fintecher.pangolin.common.enums.AssistStatus;
import cn.fintecher.pangolin.common.enums.BaseSelect;
import cn.fintecher.pangolin.common.enums.MessageType;
import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.model.AssistDistributeModel;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.PersonalAddress;
import cn.fintecher.pangolin.entity.mysql.*;
import cn.fintecher.pangolin.service.business.model.request.AssistCaseDistributeRequest;
import cn.fintecher.pangolin.service.business.model.response.AssistCaseDistributeResponse;
import cn.fintecher.pangolin.service.business.model.response.DistributeConfigResModel;
import cn.fintecher.pangolin.service.business.repository.elasticsearch.PersonalAddressElastic;
import cn.fintecher.pangolin.service.business.repository.jparepository.AssistCaseRepository;
import cn.fintecher.pangolin.service.business.repository.jparepository.CaseInfoRepository;
import cn.fintecher.pangolin.service.business.repository.jparepository.UserRepository;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Service
public class AssistCaseService {

    final Logger log = LoggerFactory.getLogger(AssistCaseService.class);

    @Autowired
    private BaseService baseService;

    @Autowired
    private AssistCaseRepository assistCaseRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private PersonalAddressElastic personalAddressElastic;


    /**
     * @Author wangxiangdong
     * @Description 外访分案预览
     * @Date 2019/9/24 10:57
     **/
    public AssistCaseDistributeResponse manualAssistDistributeCase(AssistCaseDistributeRequest request) {
        AssistCaseDistributeResponse response = new AssistCaseDistributeResponse();
        if (request.getCaseIds().isEmpty()) {
            throw new BadRequestException(null, "manualDistributeCase", "manualDistributeCase.case.isNull");
        }
        if (request.getDistributeConfigModels().isEmpty()) {
            throw new BadRequestException(null, "manualDistributeCase", "manualDistributeCase.user.isNull");
        }
        response.setCaseAmtTotal(request.getCaseAmtTotal());
        response.setCaseNumTotal(request.getCaseNumTotal());
        response.setCollectorTotal(request.getCollectorTotal());
        List<DistributeConfigResModel> distributeResults = new ArrayList<>();
        for (AssistDistributeModel reqModel : request.getDistributeConfigModels()) {
            DistributeConfigResModel resModel = new DistributeConfigResModel();
            BeanUtils.copyProperties(reqModel, resModel);
            distributeResults.add(resModel);
        }
        proAssistSysDistribute(request.getCaseIds(), distributeResults, request.getCaseNumTotal());
        response.setDistributeConfigModels(distributeResults);
        return response;
    }

    /**
     * 外访执行案件分配(综合分配)
     */
    private void proAssistSysDistribute(List<String> assisiBaseCaseList, List<DistributeConfigResModel> distributeResults, long caseNumTotal) {
        if (assisiBaseCaseList.size() > distributeResults.size()) {
            //平均数
            int pageSize = assisiBaseCaseList.size() / distributeResults.size();
            //总页数
            int copyCount = 0;
            if (assisiBaseCaseList.size() % pageSize > 0) {
                copyCount = assisiBaseCaseList.size() / pageSize + 1;
            } else {
                copyCount = assisiBaseCaseList.size() / pageSize;
            }
            for (int pageNo = 1; pageNo <= copyCount; pageNo++) {
                int startIndex = pageSize * (pageNo - 1);
                int endIndex = pageSize * pageNo;
                if (endIndex > assisiBaseCaseList.size()) {
                    endIndex = assisiBaseCaseList.size();
                }
                List<String> pageCaseList = assisiBaseCaseList.subList(startIndex, endIndex);
                if (pageNo <= distributeResults.size()) {
                    DistributeConfigResModel res = distributeResults.get(pageNo - 1);
                    for (String id : pageCaseList) {
//                        res.setLimitNum(Long.valueOf(pageSize));
                        res.setCaseNumTotal(res.getCaseNumTotal() + 1);
                        res.getResultMap().put(id, 0.0);
                        double perNum = new BigDecimal(res.getCaseNumTotal()).divide(new BigDecimal(caseNumTotal), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
                        res.setPerNum(perNum);
                    }
                } else {
                    //最后一页
                    //将分配结果从小到大排序
                    distributeResults.sort(Comparator.comparing(DistributeConfigResModel::getCaseNumTotal));
                    for (int k = 0; k < distributeResults.size(); k++) {
                        DistributeConfigResModel res = distributeResults.get(k);
                        if (k < pageCaseList.size()) {
//                            res.setLimitNum(Long.valueOf(pageSize));
                            res.setCaseNumTotal(res.getCaseNumTotal() + 1);
                            res.getResultMap().put(assisiBaseCaseList.get(k), 0.0);
                            double perNum = new BigDecimal(res.getCaseNumTotal()).divide(new BigDecimal(caseNumTotal), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
                            res.setPerNum(perNum);
                        } else {
                            break;
                        }
                    }
                }
            }
        } else {
            for (int k = 0; k < distributeResults.size(); k++) {
                DistributeConfigResModel res = distributeResults.get(k);
                if (k < assisiBaseCaseList.size()) {
//                    res.setLimitNum(0L);
                    res.setCaseNumTotal(res.getCaseNumTotal() + 1);
                    res.getResultMap().put(assisiBaseCaseList.get(k), 0.0);
                    double perNum = new BigDecimal(res.getCaseNumTotal()).divide(new BigDecimal(caseNumTotal), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    res.setPerNum(perNum);
                } else {
                    break;
                }
            }
        }
    }

    /**
     * 外访协助案件确认分配
     */
    @Transactional
    public void confirmAssistDistributeCase(AssistCaseDistributeResponse response) {
        List<DistributeConfigResModel> distributeConfigModelList = response.getDistributeConfigModels();
        List<String> caseIds = new ArrayList<>();
        List<AssistCase> resultLists = new ArrayList<>();
        for (DistributeConfigResModel obj : distributeConfigModelList) {
            User assistCollector = userRepository.findById(obj.getUserId()).get();
            Map<String, Double> resultMap = obj.getResultMap();
            List<String> assistCaseIds = new ArrayList<>();
            for (Map.Entry<String, Double> entry : resultMap.entrySet()) {
                assistCaseIds.add(entry.getKey());
            }
            BooleanBuilder booleanBuilder = new BooleanBuilder();
            booleanBuilder.and(QAssistCase.assistCase.id.in(assistCaseIds));
            Iterable<AssistCase> assistCaseIterable = assistCaseRepository.findAll(booleanBuilder);
            List<AssistCase> assistCaseList = Lists.newArrayList(assistCaseIterable);
            for (AssistCase assistCase : assistCaseList) {
                assistCase.setOperator(obj.getRealName());
                assistCase.setOperatorTime(ZWDateUtil.getNowDateTime());
                assistCase.setAssistCollector(assistCollector);
                assistCase.setAssistStatus(AssistStatus.ASSIST_COLLECTING);
                assistCase.setLastContactResult(null);
                assistCase.setLastContactDate(null);
                caseIds.add(assistCase.getCaseId());
            }
            resultLists.addAll(assistCaseList);
        }
        List<CaseInfo> caseInfoList = caseInfoRepository.findAllById(caseIds);
        caseInfoList.forEach(caseInfo -> {
            caseInfo.setIsAssist(BaseSelect.YES);
        });
        caseInfoRepository.saveAll(caseInfoList);
        if (resultLists.size() > 0) {
            assistCaseRepository.saveAll(resultLists);
        }
    }

    @Transactional
    public void endAssistCaseCollect(String assistId) {
        AssistCase assistCase = assistCaseRepository.findById(assistId).orElseThrow(() -> new BadRequestException(null, "endAssistCaseCollect", "assistCase.is.not.exist"));
        assistCase.setAssistStatus(AssistStatus.ASSIST_COMPLETED);
        if (Objects.nonNull(assistCase.getPersonalAddressId())) {
            Optional<PersonalAddress> byId = personalAddressElastic.findById(assistCase.getPersonalAddressId());
            PersonalAddress personalPerAddr = byId.get();
            personalPerAddr.setAssistFlag(BaseSelect.NO);
            personalAddressElastic.save(personalPerAddr);
        }
        CaseInfo caseInfo = caseInfoRepository.findById(assistCase.getCaseId()).orElseThrow(() -> new BadRequestException(null, "endAssistCaseCollect", "case.is.not.exist"));
        caseInfo.setIsAssist(BaseSelect.NO);
        caseInfoRepository.save(caseInfo);
        if (Objects.nonNull(caseInfo.getCurrentCollector())) {
            baseService.sendMessageToOne(MessageType.STOP_ASSIST, "结束协催", "协催人员[" + assistCase.getAssistCollector().getRealName() + "]结束了欠款人[" + caseInfo.getPersonalName() + "]的协催案件", caseInfo.getCurrentCollector().getId());
        }
        assistCaseRepository.save(assistCase);
    }
}